import Cookies from 'js-cookie'
import moment from 'moment'

export const setToken = (token, tokenName = 'token') => {
    Cookies.set(tokenName, token)
}

export const getToken = (tokenName = 'token') => {
    return Cookies.get(tokenName)
}

export const utils = {
    guid: function () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0,
                v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }
}

// 转换时间
export const dateFormat = (date) => {
    let time = new Date(date);
    let year = time.getFullYear();
    let month = Number(Number(time.getMonth()) + 1) >= 10 ? Number(time.getMonth()) + 1 : '0' + Number(Number(time.getMonth()) + 1);
    let day = Number(time.getDate()) >= 10 ? time.getDate() : '0' + time.getDate();
    return `${year}-${month}-${day}`;
}

/* *
*   惰性函数
*   @func
*   @param { elementNode } dom  绑定事件的节点对象
*   @param { string } type  绑定的事件类型
*   @param { function } fn  回调函数
* */
export const LazyEvent = {
    on (dom, type, fn) {
        if (dom.addEventListener) {
            LazyEvent.on = (dom, type, fn) => {
                dom.addEventListener(type, fn, false)
            }
        } else if (dom.attachEvent) {
            LazyEvent.on = (dom, type, fn) => {
                dom.attachEvent('on' + type, fn)
            }
        } else {
            LazyEvent.on = (dom, type, fn) => {
                dom['on' + type] = fn
            }
        }
        LazyEvent.on(dom, type, fn)
    },
    stop (dom, type, fn) {
        if (dom.removeEventListener) {
            LazyEvent.stop = (dom, type, fn) => {
                dom.removeEventListener(type, fn)
            }
        } else if (dom.detachEvent) {
            LazyEvent.stop = (dom, type, fn) => {
                dom.detachEvent(type, fn)
            }
        } else {
            LazyEvent.stop = (dom, type) => {
                dom['on' + type] = null
            }
        }
        LazyEvent.stop(dom, type, fn)
    }
}

/* *
*   筛选扩展方法
*   @param { object } confing  筛选配置，数据类型: Object，数据格式："控制字段": "status具体字段"，例如："enable":"1"
*   @param { object } obj  筛选条件的控制对象，数据类型：Object，数据格式："控制字段": true，例如："enable":true
*   @param { array } data  需要筛选的数据，数据类型：Array，数据格式：[{}, {}, {}]
*   @param { string } field    筛选依据字段，默认值为status
* */
export const filterExtend = (config, obj, data, field = 'status') => {
    let _d = data, _b = obj, _c = config, _array = [], _obj = {}, _f = field;
    if (Object.keys(_b).length === 0) return _d
    if (!_d && _d.length == 0) return _array
    _d.map((v) => {
        !_obj[v[_f]] ? (_obj[v[_f]] = [], _obj[v[_f]].push(v)) : _obj[v[_f]].push(v)
    })
    for (let k in _b) {
        if (_b[k]) _obj[_c[k]] && _array.push(..._obj[_c[k]])
    }
    return _array
}

/**
 * 防抖函数
 * @param {*需要防抖的函数} func 
 * @param {*延迟时间} wait 
 * @param {*是否立刻执行} immediate 
 */
export function debounce (func, wait, immediate) {
    let timeout
    return function (...args) {
        let self = this
        if (timeout) clearTimeout(timeout)
        if (immediate) {
            let callNow = !timeout
            timeout = setTimeout(function () {
                timeout = null
            }, wait)
            if (callNow) func.apply(self, args)
        } else {
            timeout = setTimeout(function () {
                func.apply(self, args)
            }, wait)
        }
    }
}

/**
 * 获取前一天
 * @param {日期} date 
 * @param {日期格式} format 
 */
export function getLastDay (date, format = 'YYYYMMDD') {
    // 默认获取昨天
    if (!date) return moment().subtract(1, 'days').format(format)
    // 获取指定日期的前一天
    return moment(date).subtract(1, 'days').format(format)
}

/**
 * 获取上一个月的最后一天
 * @param {日期} date 
 * @param {日期格式} format 
 */
export function getLastDayOfLastMonth (date, format = 'YYYYMMDD') {
    // 默认获取当前月
    if (!date) return moment().month(moment().month() - 1).endOf('month').format(format)
    // 根据传入日期获取
    return moment().month(moment(date).month() - 1).endOf('month').format(format)
}

/**
 * 判断是否使用当前选择月还是使用上个月
 * @param {日期} date 
 * @param {格式} format 
 */
export function validatorDate (date, format = 'YYYYMMDD') {
    let nowDate = moment().month()
    let propDate = moment(date).month()
    if (nowDate > propDate) {
        return moment().month(moment(date).month()).endOf('month').format(format)
    } else {
        return moment().month(moment().month() - 1).endOf('month').format(format)
    }
}

/**
 * 处理缓释结果表格数据
*/
export function buildTableData (data, headField = 'xAisa', dataListField = 'data', childField = 'children', setField = 'data') {
    let len = data[headField].length;
    function loop (loopData) {
        for (let i = 0, leng = loopData.length; i < leng; i++) {
            for (let j = 0; j < len; j++) {
                loopData[i][setField + (j + 1)] = loopData[i].values[j]
            }
            if (loopData[i][childField] && loopData[i][childField].length !== 0) {
                loop(loopData[i][childField])
            }
        }
    }
    loop(data[dataListField])
    return data
}


/**
 * 递归角色相关树结构，获取已经勾选的节点
 */
export function getCheckedNode (data) {
    if (!data || data.length === 0) return []
    let _readyCheck = [], _objArray = [];
    for (let i = 0, len = data.length; i < len; i++) {
        // 有子模块，没有子菜单，进入递归
        if (data[i].childModule && data[i].childModule.length !== 0 && data[i].menu.length === 0) {
            let trunData = getCheckedNode(data[i].childModule)
            _readyCheck.push(...trunData.readyArray)
            _objArray.push(...trunData.dataArray)
        }
        data[i].existed && data[i].menuId && _readyCheck.push(data[i].menuId)
        data[i].existed && data[i].menuId && _objArray.push({ menuId: data[i].menuId, moduleId: data[i].moduleId })
        // 子菜单在 menu 中
        if (data[i].menu && data[i].menu.length !== 0) {
            for (let j = 0, leng = data[i].menu.length; j < leng; j++) {
                data[i].menu[j].existed && _readyCheck.push(data[i].menu[j].menuId)
                data[i].menu[j].existed && _objArray.push({ menuId: data[i].menu[j].menuId, moduleId: data[i].menu[j].moduleId })

                // 如果子节点存在menu中
                if (data[i].menu[j].menu && data[i].menu[j].menu.length !== 0) {
                    let trunData = getCheckedNode(data[i].menu[j].menu)
                    _readyCheck.push(...trunData.readyArray)
                    _objArray.push(...trunData.dataArray)
                }

                // 如果子节点存在childMenu中
                if (data[i].menu[j].childMenu && data[i].menu[j].childMenu.length !== 0) {
                    let trunData = getCheckedNode(data[i].menu[j].childMenu)
                    _readyCheck.push(...trunData.readyArray)
                    _objArray.push(...trunData.dataArray)
                }
            }
        }

        // 子菜单在 childMenu 中
        if (data[i].childMenu && data[i].childMenu.length !== 0) {
            for (let j = 0, leng = data[i].childMenu.length; j < leng; j++) {
                data[i].childMenu[j].existed && _readyCheck.push(data[i].childMenu[j].menuId)
                data[i].childMenu[j].existed && _objArray.push({ menuId: data[i].childMenu[j].menuId, moduleId: data[i].childMenu[j].moduleId })

                // 如果子节点存在menu中
                if (data[i].childMenu[j].menu && data[i].childMenu[j].menu.length !== 0) {
                    let trunData = getCheckedNode(data[i].childMenu[j].menu)
                    _readyCheck.push(...trunData.readyArray)
                    _objArray.push(...trunData.dataArray)
                }

                // 如果子节点存在childMenu中
                if (data[i].childMenu[j].childMenu && data[i].childMenu[j].childMenu.length !== 0) {
                    let trunData = getCheckedNode(data[i].menu[j].childMenu)
                    _readyCheck.push(...trunData.readyArray)
                    _objArray.push(...trunData.dataArray)
                }
            }
        }
    }
    return {
        readyArray: _readyCheck,
        dataArray: _objArray
    }
}

/**
 * 分解树形结构 - 适用于角色授权树
 * @param {树形数据} treeData 
 */
export function resolveTree (treeData, childrenField = 'children') {
    let getArray = [], child = null;
    // 若存在子节点
    if (treeData[childrenField].length !== 0) {
        child = treeData[childrenField]
        delete treeData[childrenField]
    }
    // 存储当前节点
    getArray.push(treeData)
    // 遍历子节点
    if (child) {
        for (let i = 0, len = child.length; i < len; i++) {
            let turnData = resolveTree(child[i], childrenField)
            getArray.push(...turnData)
        }
    }
    return getArray
}
/**
 * 获取菜单的存在菜单的第一个节点
*/
export function getFirstNode (treeData) {
    let _str = ''
    if (treeData.length === 0 || !treeData) return _str
    for (let i = 0, len = treeData.length; i < len; i++) {
        if (_str) break
        // 存在子菜单
        if (treeData[i].childList && treeData[i].childList.length !== 0) {
            _str = getFirstNode(treeData[i].childList)
        }
        // 不存在子菜单且存在URL
        if ((!treeData[i].childList || treeData[i].childList.length === 0) && treeData[i].menuUrl) {
            _str = treeData[i].menuUrl
        }
    }
    return _str
}
/**
 * 根据某属性的值获取list中另一属性的值，可做翻译 val:输入的值，list：遍历的list数组，useVal：通过值，exportVal：翻译得出值，默认通过value获得label
*/
export function getLabel (val, list = [], useVal = "value", exportVal = "label") {
    var label = ""
    for (let i = 0; i < list.length; i++) {
        if (val == list[i][useVal]) { label = list[i][exportVal] }
    }
    if (!label) { label = val }
    return label
}
export function getNameByCode (val, list = [], useVal = "code", exportVal = "name") {
    var label = ""
    for (let i = 0; i < list.length; i++) {
        if (val == list[i][useVal]) { label = list[i][exportVal] }
    }
    if (!label) { label = val }
    return label
}
/**
 ** ♥ 根据传入字符,递归获取具有层级结构数据中对应节点属性值，层级结构最外层为[]或{}均可。
 ** @param {传入的字符} onlyCode 
 ** @param {递归的树形数据} treeData 
 ** @param {节点编码，不传默认是value} code 
 ** @param {节点名称，不传默认是label} name 
 ** @param {内嵌数组对象集合的属性名称，不传默认为children} childName  
 **/
export const getNameFromTree = (onlyCode, treeData, code = "value", name = "label", childName = "children") => {
    let resultName = ""
    if (!treeData || !onlyCode) return ""
    const getChild = (treeData) => {
        // 外层是对象的处理
        if (!(treeData instanceof Array)) {
            if (onlyCode == treeData[code]) { resultName = treeData[name]; return resultName }
            if (treeData[childName] && treeData[childName].length > 0) { getChild(treeData[childName]) }
        }
        // 外层是数组的处理
        for (let i = 0; i < treeData.length; i++) {
            if (onlyCode == treeData[i][code]) { resultName = treeData[i][name]; break } else { resultName = "" }
            if (treeData[i][childName] && treeData[i][childName].length > 0) {
                getChild(treeData[i][childName])
            }
        }
        return resultName
    }
    return getChild(treeData)
}

/**
         * 将list装换成tree
         * @param {Object} myId  数据主键id
         * @param {Object} pId     数据关联的父级id
         * @param {Object} list list集合
         */
export const listToTree = (myId = "id", pId = "parentId", list) => {
    if (list.length == 0) { return list }
    function exists (list, parentId) {
        for (var i = 0; i < list.length; i++) {
            if (list[i][myId] == parentId) return true;
        }
        return false;
    }

    var nodes = [];
    // get the top level nodes
    for (var i = 0; i < list.length; i++) {
        var row = list[i];
        if (!exists(list, row[pId])) {
            nodes.push(row);
        }
    }

    var toDo = [];
    for (var i = 0; i < nodes.length; i++) {
        toDo.push(nodes[i]);
    }
    while (toDo.length) {
        var node = toDo.shift();    // the parent node
        // get the children nodes
        for (var i = 0; i < list.length; i++) {
            var row = list[i];
            if (row[pId] == node[myId]) {
                //var child = {id:row.id,text:row.name};
                if (node.children) {
                    node.children.push(row);
                } else {
                    node.children = [row];
                }
                toDo.push(row);
            }
        }
    }
    return nodes;
}

/* table表格展示列使用函数 ，返回一个数组
 checkList  选中列中文字段数组
 textData 参考列字段数组
**/
export const tableDataPick = (checkList = [], textData = []) => {
    let arr = [],
        arr1 = textData,
        arr2 = checkList;
    for (let i = 0; i < arr1.length; i++) {
        let flg = false;
        for (let j = 0; j < arr2.length; j++) {
            if (arr1[i].label === arr2[j]) {
                flg = true;
            }
        }
        arr.push(flg);
    }
    return arr;
}

// 随机字符
export const randomStr = {
    guid: function () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0,
                v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }
}

/**
 * deep  copy 深度拷贝
 * @param source
 * @return {*}
 */
export const deepClone = (source) => {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'deepClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            targetObj[keys] = deepClone(source[keys])
        } else {
            targetObj[keys] = source[keys]
        }
    })
    return targetObj
}

/*防抖函数*/
export const _debounce = (handler, delay, context) => {
    let timer = null
    return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
            handler.apply(context)
        }, delay)
    }
}
/*节流函数*/
export const _throttle = (handler, wait, context) => {
    let lastTime = 0
    return function () {
        let now = new Date().getTime()
        if (now - lastTime > wait) {
            handler.apply(context)
            lastTime = now
        }
    }
}